package com.sl.transport.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.itheima.em.sdk.EagleMapTemplate;
import com.itheima.em.sdk.enums.ProviderEnum;
import com.itheima.em.sdk.vo.Coordinate;
import com.sl.transport.common.exception.SLException;
import com.sl.transport.common.util.PageResponse;
import com.sl.transport.domain.OrganDTO;
import com.sl.transport.domain.TransportLineNodeDTO;
import com.sl.transport.domain.TransportLineSearchDTO;
import com.sl.transport.entity.line.TransportLine;
import com.sl.transport.entity.node.AgencyEntity;
import com.sl.transport.entity.node.BaseEntity;
import com.sl.transport.entity.node.OLTEntity;
import com.sl.transport.entity.node.TLTEntity;
import com.sl.transport.enums.ExceptionEnum;
import com.sl.transport.enums.TransportLineEnum;
import com.sl.transport.repository.TransportLineRepository;
import com.sl.transport.service.OrganService;
import com.sl.transport.service.TransportLineService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.sl.transport.enums.ExceptionEnum.TRANSPORT_LINE_ALREADY_EXISTS;
import static com.sl.transport.enums.ExceptionEnum.TRANSPORT_LINE_TYPE_ERROR;

@Service
public class TransportLineServiceImpl implements TransportLineService {

    @Resource
    private TransportLineRepository transportLineRepository;
    @Resource
    private OrganService organService;


    /**
     * 新增路线
     * @param transportLine 路线数据
     * @return
     */
    @Override
    public Boolean createLine(TransportLine transportLine) {
        // 1. 参数校验  路线类型  起点和终点不能相同
        TransportLineEnum transportLineEnum = TransportLineEnum.codeOf(transportLine.getType());
        if (transportLineEnum == null){
            throw new SLException(TRANSPORT_LINE_TYPE_ERROR);
        }

        if (ObjectUtil.equals(transportLine.getStartOrganId(),transportLine.getEndOrganId())){
            throw new SLException(ExceptionEnum.START_END_ORGAN_CANNOT_EQUAL);
        }
        // 2. 构建起点和终点网点 (路线类型)
        BaseEntity startNode;
        BaseEntity endNode;
        switch (transportLineEnum){
            case TRUNK_LINE:
                // 干线
                startNode = OLTEntity.builder().bid(transportLine.getStartOrganId()).build();
                endNode = OLTEntity.builder().bid(transportLine.getEndOrganId()).build();
                break;
            case BRANCH_LINE:
                startNode = TLTEntity.builder().bid(transportLine.getStartOrganId()).build();
                endNode = OLTEntity.builder().bid(transportLine.getEndOrganId()).build();
                break;
            case CONNECT_LINE:
                startNode = AgencyEntity.builder().bid(transportLine.getStartOrganId()).build();
                endNode = TLTEntity.builder().bid(transportLine.getEndOrganId()).build();
                break;
            default:
                throw new SLException(TRANSPORT_LINE_TYPE_ERROR);
        }
        // 3. 判断两个网点间是否已经存在路线
        Long count = this.transportLineRepository.queryCount(startNode, endNode);
        if (count > 0){
            throw new SLException(TRANSPORT_LINE_ALREADY_EXISTS);
        }

        // 4. 补全路线数据   时间    ==>  距离   行驶时间   路线成本
        transportLine.setId(null);
        transportLine.setCreated(System.currentTimeMillis());
        transportLine.setUpdated(System.currentTimeMillis());
        initForMap(startNode,endNode,transportLine);
        // 5. 构建路线
        Long createCount = this.transportLineRepository.create(startNode, endNode, transportLine);
        return createCount>0;
    }

    @Resource
    private EagleMapTemplate eagleMapTemplate;

    private void initForMap(BaseEntity startNode, BaseEntity endNode, TransportLine transportLine) {
        // 1. 参数校验  起点和终点网点要有经纬度
        OrganDTO startOrgan = organService.findByBid(startNode.getBid());
        if (ObjectUtil.hasEmpty(startOrgan.getLongitude(),startOrgan.getLatitude())){
            throw new SLException(ExceptionEnum.ORGAN_INFO_ERROR);
        }
        OrganDTO endOrgan = organService.findByBid(endNode.getBid());
        if (ObjectUtil.hasEmpty(endOrgan.getLongitude(),endOrgan.getLatitude())){
            throw new SLException(ExceptionEnum.ORGAN_INFO_ERROR);
        }
        // 2. 调用高德地图 (汽车驾驶路线接口 : json路线)
        Coordinate start = new Coordinate(startOrgan.getLongitude(),startOrgan.getLatitude());
        Coordinate end = new Coordinate(endOrgan.getLongitude(),endOrgan.getLatitude());
        Map<String, Object> params = new HashMap<>();
        params.put("show_fields", "cost");
        String driving = eagleMapTemplate.opsForDirection().driving(ProviderEnum.AMAP, start, end, params);
        JSONObject drivingObj = JSONUtil.parseObj(driving);

        // 3. 解析json路线 得到 持续时间    距离
        Double distance = Convert.toDouble(drivingObj.getByPath("route.paths[0].distance"),-1D);
        transportLine.setDistance(distance);

        Long time = Convert.toLong(drivingObj.getByPath("route.paths[0].cost.duration"), -1L);
        transportLine.setTime(time);
        // 4. 成本
    }

    @Override
    public Boolean updateLine(TransportLine transportLine) {
        return null;
    }

    @Override
    public Boolean deleteLine(Long id) {
        return null;
    }

    @Override
    public PageResponse<TransportLine> queryPageList(TransportLineSearchDTO transportLineSearchDTO) {
        return null;
    }

    @Override
    public TransportLineNodeDTO queryShortestPath(Long startId, Long endId) {
        return null;
    }

    @Override
    public TransportLineNodeDTO findLowestPath(Long startId, Long endId) {
        return null;
    }

    @Override
    public TransportLineNodeDTO queryPathByDispatchMethod(Long startId, Long endId) {
        return null;
    }

    @Override
    public List<TransportLine> queryByIds(Long... ids) {
        return null;
    }

    @Override
    public TransportLine queryById(Long id) {
        return null;
    }
}
